package cn.wolfcode.luowowo.redis.service.impl;

import cn.wolfcode.luowowo.article.domain.StrategyDetail;
import cn.wolfcode.luowowo.article.service.IStrategyDetailService;
import cn.wolfcode.luowowo.common.util.DateUtil;
import cn.wolfcode.luowowo.redis.domian.StrategyStatisVO;
import cn.wolfcode.luowowo.redis.service.IStrategyStatisVoRedisService;
import cn.wolfcode.luowowo.redis.util.BeanUtil;
import cn.wolfcode.luowowo.redis.util.RedisKeys;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatisVoRedisServiceImpl implements IStrategyStatisVoRedisService {
    public static final int STRATEGY_STATIS_TYPE_VIEWNUM = 1; //阅读数
    public static final int STRATEGY_STATIS_TYPE_REPLYNUM = 2; //评论数
    public static final int STRATEGY_STATIS_TYPE_FAVORNUM = 3;  //收藏数
    public static final int STRATEGY_STATIS_TYPE_SHARENUM = 4;  //分享数
    public static final int STRATEGY_STATIS_TYPE_THUMBSUPNUM = 5; //点赞数

    @Autowired
    private StringRedisTemplate template;
    @Reference
    private IStrategyDetailService strategyDetailService;


/*
    @Override
    public void viewnumIncrease(Long id, int num) {
        String key = RedisKeys.STRATEGY_STATIS_VO.getKey(id.toString());
        //查询  无论返回哪个第一次还是很多次的vo都是一样
        StrategyStatisVO vo = this.getStrategyStatisVo(id);
         //添加 +
         vo.setViewnum(vo.getViewnum() + num);
        template.opsForValue().set(key, JSON.toJSONString(vo));
    }*/

    @Override
    public void viewnumIncrease(Long id, int num) {
        numIncreaes(id,num,STRATEGY_STATIS_TYPE_VIEWNUM);
    }


  /* @Override
    public int replynumIncrease(Long sid, int num) {
       numIncreaes(sid,num,STRATEGY_STATIS_TYPE_VIEWNUM);
       StrategyStatisVO vo = this.getStrategyStatisVo(sid);
       return vo.getReplynum();
    }*/

    @Override
    public int replynumIncrease(Long sid, int num) {
         String key  = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        StrategyStatisVO vo = this.getStrategyStatisVo(sid);
        vo.setReplynum(vo.getReplynum() + num);
        //保存到redis
        template.opsForValue().set(key,JSON.toJSONString(vo));
        return vo.getReplynum();
    }

    @Override
    public Boolean favor(Long sid, Long uid) {
        Boolean flag = false;
        //key :key  vaule:[userId]
        String key  = RedisKeys.STRATEGY_STATIS_FAVOR.getKey(sid.toString());
        List<Long> userIds = null;
        if(template.hasKey(key)){
            //有收藏用户列表
               //如果存在  查询
            String strVo = template.opsForValue().get(key);
            userIds = JSON.parseArray(strVo, Long.class);
        }else{
            //没有收藏用户列表
            userIds = new ArrayList<>();
        }

        StrategyStatisVO vo = this.getStrategyStatisVo(sid);
        if (userIds.contains(uid)){
            //如果已经有表示收藏,表示当前吧收藏-1
            vo.setFavornum(vo.getFavornum() - 1);
            userIds.remove(uid);

        }else {
            //如果没有,表示第一次收藏,添加进去
            vo.setFavornum(vo.getFavornum() + 1);
            userIds.add(uid);
            flag = true;
        }


        //统一更新
        template.opsForValue().set(key,JSON.toJSONString(userIds));
        String vokey  = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        template.opsForValue().set(vokey,JSON.toJSONString(vo));
        return flag;
    }


    public Boolean getbyUserIdAndSid(Long sid, Long uid) {
       String key = RedisKeys.STRATEGY_STATIS_FAVOR.getKey(sid.toString());
        List<Long> userIds = null;
        if (template.hasKey(key)) {
            //有收藏用户列表
            //如果存在  查询
            String strVo = template.opsForValue().get(key);
            userIds = JSON.parseArray(strVo, Long.class);
            if (userIds.contains(uid)) {
                return true;
            }
        }
        return false;
    }

    /**
     *逻辑:
     *  1.从redisUtil用sid查出key,判断redis是否存在这个key
     *  2.如果不存在设置一个点赞key,将vo对象的点赞数+1 return ture
     *  3.如果存在代表今天已经点赞过 return false
     */
    @Override
    public Boolean thumbup(Long sid, Long uid) {
        Boolean flag = false;
        //1.判断是否是今天是否是第一次点赞
        String key = RedisKeys.STRATEGY_STATIS_THUMBUP.getKey(sid.toString());
        if(!template.hasKey(key)) {
            //点赞数+1
            this.numIncreaes(sid,1,STRATEGY_STATIS_TYPE_THUMBSUPNUM);
            //如果没有说明今天第一次点赞
            //过期时间为24点-当前时间  工具类
            //今天的最后的时间23.59.59秒
            Date endDate = DateUtil.getEndDate(new Date());
            //获取过期时间,23.59.59-当前时间
            long value = DateUtil.getDateBetween(new Date(), endDate);
            template.opsForValue().set(key, "1", value, TimeUnit.SECONDS);
            flag = true;
        }
        return flag;
    }

       @Override
    public void setStrategyStatisVo(StrategyStatisVO vo) {
        //一条攻略文章存一个vo对象
        String vokey  = RedisKeys.STRATEGY_STATIS_VO.getKey(vo.getStrategyId().toString());
        template.opsForValue().set(vokey,JSON.toJSONString(vo));
    }

    @Override
    public boolean isExistStrategyVoKey(Long sid) {
        String vokey  = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        //如果存在返回true
        if(template.hasKey(vokey)){
            return true;
        }
        return false;
    }

    @Override
    public List<StrategyStatisVO> listStrategyStatisVo(String voKey) {
        //查出所有攻略vo list
        Set<String> sets = template.keys(voKey);

        List<StrategyStatisVO> list = new ArrayList<>();
        for (String set : sets) {
            String voStr = template.opsForValue().get(set);
            list.add(JSON.parseObject(voStr,StrategyStatisVO.class));
        }
        return list;
    }

    @Override
    public void addHotScore(Long sid, int num) {
        /** zset操作   阅读访问分数+1
         * key                             value                   score
         * strategy_zset_sort_hot       strategy_statis_vo:sid       1
         */
        String key = RedisKeys.STRATEGY_ZSET_SORT_HOT.getPrefix();
        String value  = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        template.opsForZSet().incrementScore(key,value,num);
    }

    @Override
    public List<StrategyStatisVO> listHotVoTop10() {
        String key = RedisKeys.STRATEGY_ZSET_SORT_HOT.getPrefix();
        //查询分数前10条数据
        Set<String> voKeys = template.opsForZSet().reverseRange(key, 0, 9);
        List<StrategyStatisVO> list = new ArrayList<>();
        for (String voKey : voKeys) {
            String voStr = template.opsForValue().get(voKey);
            StrategyStatisVO vo = JSON.parseObject(voStr, StrategyStatisVO.class);
            list.add(vo);
        }
        return list;
    }

    @Override
    public void addIsAbroadCommend(Long sid, int num) {
        String key = RedisKeys.STRATEGY_ZSET_SORT_ISABROAD.getPrefix();
        String value = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        template.opsForZSet().incrementScore(key,value,num);
    }

    @Override
    public List<StrategyStatisVO> listIsAbroadCommendVo() {
        String prefix = RedisKeys.STRATEGY_ZSET_SORT_ISABROAD.getPrefix();
        Set<String> sets = template.opsForZSet().reverseRange(prefix, 0, -1);
        List<StrategyStatisVO> list = new ArrayList<>();
        if(sets!=null && sets.size()>0){
            for (String set : sets) {
                list.add(JSON.parseObject(template.opsForValue().get(set),StrategyStatisVO.class));
            }
        }
        return list;
    }

    @Override
    public boolean isZsetStatisVoExeist(String ZKey, Long sid) {
        String key = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        //返回对应key对应值的分数,如果有分数代表这个key里的这个值存在
        Long rank = template.opsForZSet().rank(ZKey, key);
        return rank!=null;
    }


    private void numIncreaes(Long sid, int num,int type){
        String key  = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        StrategyStatisVO vo = this.getStrategyStatisVo(sid);
        switch (type){
            case STRATEGY_STATIS_TYPE_VIEWNUM:
                vo.setViewnum(vo.getViewnum() + num);
                break;
            case STRATEGY_STATIS_TYPE_REPLYNUM:
                vo.setReplynum(vo.getReplynum() + num);
                break;
            case STRATEGY_STATIS_TYPE_FAVORNUM:
                vo.setFavornum(vo.getFavornum() + num);
                break;
            case STRATEGY_STATIS_TYPE_SHARENUM:
                vo.setSharenum(vo.getSharenum() + num);
                break;
            case STRATEGY_STATIS_TYPE_THUMBSUPNUM:
                vo.setThumbsupnum(vo.getThumbsupnum() + num);
                break;
        }
        template.opsForValue().set(key, JSON.toJSONString(vo));
    }
    @Override
    public StrategyStatisVO getStrategyStatisVo(Long sid) {
        //1.判断是否有这个key     查询
        String key = RedisKeys.STRATEGY_STATIS_VO.getKey(sid.toString());
        StrategyStatisVO vo = null;
        if (template.hasKey(key)){
            //如果存在
            String voStr = template.opsForValue().get(key);
            vo = JSON.parseObject(voStr,StrategyStatisVO.class);
        }else {
            //如果不存在
            //创建vo对象,从数据库查出数据初始化数据
            vo = new StrategyStatisVO();
            StrategyDetail detail = strategyDetailService.get(sid);
            BeanUtil.copyProperties(vo,detail);
            vo.setDestId(detail.getDest().getId());
            vo.setDestName(detail.getDest().getName());
            vo.setStrategyId(detail.getId());
        }
        return vo;
    }

}
